package com.project.harmonyledger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.project.harmonyledger.common.response.Result;
import com.project.harmonyledger.common.response.ResultCode;
import com.project.harmonyledger.mapper.AccountMapper;
import com.project.harmonyledger.mapper.TransactionMapper;
import com.project.harmonyledger.pojo.Account;
import com.project.harmonyledger.pojo.Transaction;
import com.project.harmonyledger.pojo.User;
import com.project.harmonyledger.service.TransactionService;
import com.project.harmonyledger.utils.UserDetailsImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class TransactionServiceImpl implements TransactionService {
  @Autowired
  private TransactionMapper transactionMapper;

  @Autowired
  private AccountMapper accountMapper;

  private User getCurrentUser() {
    UserDetailsImpl loginUser = (UserDetailsImpl) SecurityContextHolder.getContext()
        .getAuthentication().getPrincipal();
    return loginUser.getUser();
  }

  @Override
  @Transactional
  public Result<Map<String, String>> createTransaction(Long accountId, Long categoryId,
      BigDecimal amount, String type, String description, Date transactionDate) {
    Map<String, String> map = new HashMap<>();

    // 验证参数
    if (accountId == null || categoryId == null || amount == null || type == null) {
      return Result.error(ResultCode.BAD_REQUEST);
    }

    // 验证账户所有权
    Account account = accountMapper.selectById(accountId);
    if (account == null) {
      return Result.error(ResultCode.ACCOUNT_NOT_FOUND);
    }
    if (!account.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      // 创建交易记录
      Transaction transaction = new Transaction();
      transaction.setUserId(getCurrentUser().getId().longValue());
      transaction.setAccountId(accountId);
      transaction.setCategoryId(categoryId);
      transaction.setAmount(amount);
      transaction.setType(type);
      transaction.setDescription(description);
      transaction.setTransactionDate(transactionDate != null ? transactionDate : new Date());
      transaction.setCreatedAt(new Date());
      transaction.setUpdatedAt(new Date());

      transactionMapper.insert(transaction);

      // 更新账户余额
      if ("INCOME".equals(type)) {
        account.setBalance(account.getBalance().add(amount));
      } else if ("EXPENSE".equals(type)) {
        if (account.getBalance().compareTo(amount) < 0) {
          return Result.error(ResultCode.BALANCE_NOT_ENOUGH);
        }
        account.setBalance(account.getBalance().subtract(amount));
      }
      accountMapper.updateById(account);

      map.put("message", "交易创建成功");
      return Result.success(map);

    } catch (Exception e) {
      log.error("创建交易失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }

  @Override
  @Transactional
  public Result<Map<String, String>> deleteTransaction(Long transactionId) {
    Map<String, String> map = new HashMap<>();

    Transaction transaction = transactionMapper.selectById(transactionId);
    if (transaction == null) {
      return Result.error(ResultCode.TRANSACTION_NOT_FOUND);
    }

    // 验证所有权
    if (!transaction.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      // 恢复账户余额
      Account account = accountMapper.selectById(transaction.getAccountId());
      if ("INCOME".equals(transaction.getType())) {
        account.setBalance(account.getBalance().subtract(transaction.getAmount()));
      } else if ("EXPENSE".equals(transaction.getType())) {
        account.setBalance(account.getBalance().add(transaction.getAmount()));
      }
      accountMapper.updateById(account);

      // 删除交易记录
      transactionMapper.deleteById(transactionId);

      map.put("message", "交易删除成功");
      return Result.success(map);

    } catch (Exception e) {
      log.error("删除交易失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }

  @Override
  @Transactional
  public Result<Map<String, String>> updateTransaction(Long transactionId, Long categoryId,
      BigDecimal amount, String description) {
    Map<String, String> map = new HashMap<>();

    Transaction transaction = transactionMapper.selectById(transactionId);
    if (transaction == null) {
      return Result.error(ResultCode.TRANSACTION_NOT_FOUND);
    }

    // 验证所有权
    if (!transaction.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      // 更新交易记录
      if (categoryId != null)
        transaction.setCategoryId(categoryId);
      if (description != null)
        transaction.setDescription(description);
      if (amount != null) {
        Account account = accountMapper.selectById(transaction.getAccountId());

        // 恢复原余额
        if ("INCOME".equals(transaction.getType())) {
          account.setBalance(account.getBalance().subtract(transaction.getAmount()));
        } else if ("EXPENSE".equals(transaction.getType())) {
          account.setBalance(account.getBalance().add(transaction.getAmount()));
        }

        // 设置新金额
        transaction.setAmount(amount);

        // 更新新余额
        if ("INCOME".equals(transaction.getType())) {
          account.setBalance(account.getBalance().add(amount));
        } else if ("EXPENSE".equals(transaction.getType())) {
          if (account.getBalance().compareTo(amount) < 0) {
            return Result.error(ResultCode.BALANCE_NOT_ENOUGH);
          }
          account.setBalance(account.getBalance().subtract(amount));
        }
        accountMapper.updateById(account);
      }

      transaction.setUpdatedAt(new Date());
      transactionMapper.updateById(transaction);

      map.put("message", "交易更新成功");
      return Result.success(map);

    } catch (Exception e) {
      log.error("更新交易失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }

  @Override
  public Result<Map<String, String>> getTransactionById(Long transactionId) {
    Transaction transaction = transactionMapper.selectById(transactionId);
    if (transaction == null) {
      return Result.error(ResultCode.TRANSACTION_NOT_FOUND);
    }

    // 验证所有权
    if (!transaction.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    Map<String, String> map = new HashMap<>();
    map.put("id", transaction.getId().toString());
    map.put("accountId", transaction.getAccountId().toString());
    map.put("categoryId", transaction.getCategoryId().toString());
    map.put("amount", transaction.getAmount().toString());
    map.put("type", transaction.getType());
    map.put("description", transaction.getDescription());
    map.put("transactionDate", transaction.getTransactionDate().toString());

    return Result.success(map);
  }

  @Override
  public Result<List<Transaction>> getTransactionsByAccountId(Long accountId) {
    // 验证账户所有权
    Account account = accountMapper.selectById(accountId);
    if (account == null) {
      return Result.error(ResultCode.ACCOUNT_NOT_FOUND);
    }
    if (!account.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    QueryWrapper<Transaction> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("account_id", accountId)
        .orderByDesc("transaction_date");

    return Result.success(transactionMapper.selectList(queryWrapper));
  }

  @Override
  public Result<List<Transaction>> getTransactionsByDateRange(Date startDate, Date endDate) {
    return null;
  }

  @Override
  public Result<Map<String, Object>> getAccountStatistics(Long accountId, Date startDate, Date endDate) {
    Map<String, Object> result = new HashMap<>();

    // 验证参数
    if (accountId == null || startDate == null || endDate == null) {
      return Result.error(ResultCode.BAD_REQUEST);
    }

    // 验证账户所有权
    Account account = accountMapper.selectById(accountId);
    if (account == null) {
      return Result.error(ResultCode.ACCOUNT_NOT_FOUND);
    }
    if (!account.getUserId().equals(getCurrentUser().getId().longValue())) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      List<Map<String, Object>> statistics = transactionMapper.getAccountStatistics(
          accountId, startDate, endDate);

      BigDecimal totalIncome = BigDecimal.ZERO;
      BigDecimal totalExpense = BigDecimal.ZERO;

      for (Map<String, Object> stat : statistics) {
        if ("INCOME".equals(stat.get("type"))) {
          totalIncome = new BigDecimal(stat.get("total").toString());
        } else if ("EXPENSE".equals(stat.get("type"))) {
          totalExpense = new BigDecimal(stat.get("total").toString());
        }
      }

      result.put("accountName", account.getName());
      result.put("totalIncome", totalIncome);
      result.put("totalExpense", totalExpense);
      result.put("balance", totalIncome.subtract(totalExpense));
      result.put("startDate", startDate);
      result.put("endDate", endDate);

      return Result.success(result);

    } catch (Exception e) {
      log.error("获取账户统计失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }

  @Override
  public Result<Map<String, Object>> getAllAccountsStatistics(String userId, Date startDate, Date endDate) {
    // 验证用户权限
    if (!getCurrentUser().getId().toString().equals(userId)) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      List<Map<String, Object>> statistics = transactionMapper.getAllAccountsStatistics(
          userId, startDate, endDate);

      Map<String, Object> result = new HashMap<>();
      List<Map<String, Object>> accountList = new ArrayList<>();

      Map<String, Map<String, BigDecimal>> tempStats = new HashMap<>();
      BigDecimal totalIncome = BigDecimal.ZERO;
      BigDecimal totalExpense = BigDecimal.ZERO;

      // 先按账户名分组统计
      for (Map<String, Object> stat : statistics) {
        String accountName = stat.get("accountName").toString();
        String type = stat.get("type").toString();
        BigDecimal amount = new BigDecimal(stat.get("total").toString());

        tempStats.computeIfAbsent(accountName, k -> new HashMap<>());
        tempStats.get(accountName).put(type, amount);

        if ("INCOME".equals(type)) {
          totalIncome = totalIncome.add(amount);
        } else if ("EXPENSE".equals(type)) {
          totalExpense = totalExpense.add(amount);
        }
      }

      // 转换为列表格式
      for (Map.Entry<String, Map<String, BigDecimal>> entry : tempStats.entrySet()) {
        Map<String, Object> accountStat = new HashMap<>();
        accountStat.put("accountName", entry.getKey());
        accountStat.put("income", entry.getValue().getOrDefault("INCOME", BigDecimal.ZERO).toString());
        accountStat.put("expense", entry.getValue().getOrDefault("EXPENSE", BigDecimal.ZERO).toString());
        accountList.add(accountStat);
      }

      result.put("accountList", accountList);
      result.put("totalIncome", totalIncome.toString());
      result.put("totalExpense", totalExpense.toString());
      result.put("netBalance", totalIncome.subtract(totalExpense).toString());
      result.put("startDate", startDate.toString());
      result.put("endDate", endDate.toString());

      return Result.success(result);

    } catch (Exception e) {
      log.error("获取所有账户统计失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }

  @Override
  public Result<List<Transaction>> getUserAllTransactions(String userId, Date startDate, Date endDate) {
    // 验证用户权限
    if (!getCurrentUser().getId().toString().equals(userId)) {
      return Result.error(ResultCode.FORBIDDEN);
    }

    try {
      QueryWrapper<Transaction> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("user_id", userId);

      // 如果提供了日期范围，添加日期过滤
      if (startDate != null && endDate != null) {
        queryWrapper.between("transaction_date", startDate, endDate);
      }

      // 按时间倒序排序
      queryWrapper.orderByDesc("transaction_date");

      List<Transaction> transactions = transactionMapper.selectList(queryWrapper);
      return Result.success(transactions);

    } catch (Exception e) {
      log.error("获取用户交易记录失败: {}", e.getMessage());
      return Result.error(ResultCode.SYSTEM_ERROR);
    }
  }
}